Estoy tratando de enviar instrucciones desde un sitio web de Django a un robot (Raspberry Pi) usando Sockets, pero cada vez que intento enviar una segunda instrucción desde el sitio web, aparece el error. Si tiene alguna idea de qué está causando esto, ¡la ayuda sería increíble! Vista de envío del sitio web:
def form_valid(self, form, **kwargs): robo_pk = self.kwargs['pk'] robo = Robot.objects.get(pk=robo_pk) PORT = robo.port SERVER = robo.server ADDR = (SERVER, PORT) self.object = form.save() client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect(ADDR) def send(msg): message = msg.encode(FORMAT) msg_length = len(message) send_length = str(msg_length).encode(FORMAT) send_length += b' ' * (HEADER - len(send_length)) client.send(send_length) client.send(message) send(form.cleaned_data['path_options']) send("MESSAGE SENT :) !") send(DISCONNECT_MESSAGE) return render(self.request, "dashboard-home/thank-you.html")RASTREO DE ERRORES:
Traceback (most recent call last): File "/usr/lib/python3.7/threading.py", line 917, in _bootstrap_inner self.run() File "/usr/lib/python3.7/threading.py", line 865, in run self._target(*self._args, **self._kwargs) File "main.py", line 46, in handle_client conn.send("MSG Received".encode(FORMAT)) BrokenPipeError: [Errno 32] Broken pipeCódigo relevante:
def handle_client(conn, addr): print(f"[NEW CONNECTION] {addr} connected") connected = True while connected: msg_length = conn.recv(HEADER).decode(FORMAT) if msg_length: msg_length = int(msg_length) msg = conn.recv(msg_length).decode(FORMAT) if msg == '!DISCONNECT!': connected = False print("disconnect") break else: my_queue.put(msg) print(f"[{ADDR}] {msg}") conn.send("MSG Received".encode(FORMAT)) conn.close() def start(): server.listen() print(f"[LISTENING] Server Is Listening On {SERVER}") while True: print("before") conn,addr = server.accept() print("after") thread = threading.Thread(target=handle_client, args=(conn, addr)) thread.start() print(f"[ACTIVE CONNECTIONS] {threading.activeCount()}") print("[Starting] Server") threading.Thread(target=start).start() msg = my_queue.get()Está desconectando el cliente antes de recibir todos los mensajes. Para demostrar esto, ejecute de nuevo con conn.close comentado. Le falta lógica adicional para asegurarse de que todas las solicitudes pendientes se hayan procesado antes de cerrar la conexión.
El cliente Django se desconecta inmediatamente después de enviar DISCONNECT_MESSAGE. El servidor detecta el cierre de la conexión e invalida el conector de conexión, lo que provoca la excepción. Esta invalidación puede ocurrir, por ejemplo, entre recv() para el mensaje "MENSAJE ENVIADO :)" y la respuesta del servidor (conn.send()) a este.
Consulte ¿Cómo manejar una tubería rota (SIGPIPE) en Python? para más información.